-- local login = require "snax.loginserver"
-- local crypt = require "skynet.crypt"
-- local skynet = require "skynet"


-- local server = {
--     host = "127.0.0.1",
--     port = 9000,
--     multilogin = false, -- disallow multilogin
--     name = "login_master",
-- }

-- function server.auth_handler(token)
--     -- the token is base64(user)@base64(server):base64(password)
--     --通过正则表达式，解析出各个参数
--     local user, server, password = token:match("([^@]+)@([^:]+):(.+)")
--     user = crypt.base64decode(user)
--     server = crypt.base64decode(server)
--     password = crypt.base64decode(password)
--     skynet.error(string.format("%s@%s:%s", user, server, password))
--     --密码不对直接报错中断当前协程，千万不要返回nil值，一定要用assert中断或者error报错终止掉当前协程
--     assert(password == "password", "Invalid password") 
--     return server, user
-- end


-- -- 其实不允许重复登录主要是login_handler不允许重入，因为如果重入了login_handler会造成subid分配出现并入。
-- local subid = 0
-- function server.login_handler(server, uid, secret)
--     skynet.error(string.format("%s@%s is login, secret is %s", uid, server, crypt.hexencode(secret)))
--     -- error("login_handler") --加入这一行,终止掉当前协程
--     subid = subid + 100 --分配一个唯一的subid
--     -- skynet.sleep(500) --添加延时
--     return subid
-- end


-- local CMD = {}
-- function CMD.register_gate(server, address)
--     skynet.error("cmd register_gate")
-- end

-- --实现command_handler，必须要实现，用来处理lua消息
-- function server.command_handler(command, ...) 
--     local f = assert(CMD[command])
--     return f(...)
-- end

-- login(server) --服务启动需要参数


-- ​需要注意，一旦有登录请求进来，在调用回调函数server.auth_handlery以及 server.login_handler
-- 都是开启了一个协程来处理，assert与error都能终止掉当前协程，并不是终止掉整个服务。

-- ​虽然我们在启动mylogin服务的时候一下启动的了9个服务，但这9个服务中一个是监听使用，其他服务负责
-- 与客户端交换密钥以及处理账号验证，八个服务共同分担处理任务，可以通过不断启动客户端来观察。八个
-- 服务轮流处理一次登录请求。

-- myloginserver
-- [:01000010] LAUNCH snlua myloginserver
-- [:01000012] LAUNCH snlua myloginserver
-- [:01000019] LAUNCH snlua myloginserver
-- [:0100001a] LAUNCH snlua myloginserver
-- [:0100001b] LAUNCH snlua myloginserver
-- [:0100001c] LAUNCH snlua myloginserver
-- [:0100001d] LAUNCH snlua myloginserver
-- [:0100001e] LAUNCH snlua myloginserver
-- [:0100001f] LAUNCH snlua myloginserver
-- [:01000010] login server listen at : 127.0.0.1 9000
-- [:01000012] connect from 127.0.0.1:54466 (fd = 9)
-- [:01000012] hello@sample:password
-- [:01000010] hello@sample is login, secret is 26d3fc4a69cc6c10
-- [:01000019] connect from 127.0.0.1:54470 (fd = 10)
-- [:01000019] hello@sample:password
-- [:01000010] hello@sample is login, secret is 29202aeda1817c8c
-- [:0100001a] connect from 127.0.0.1:54482 (fd = 11)
-- [:0100001a] hello@sample:password
-- [:01000010] hello@sample is login, secret is 20f1730de857872c
-- [:0100001b] connect from 127.0.0.1:54488 (fd = 12)
-- [:0100001b] hello@sample:password
-- [:01000010] hello@sample is login, secret is 928baa06ba5ecfa5
-- [:0100001c] connect from 127.0.0.1:54498 (fd = 13)
-- [:0100001c] hello@sample:password
-- [:01000010] hello@sample is login, secret is e16670c1dda2751e
-- [:0100001d] connect from 127.0.0.1:54508 (fd = 14)
-- [:0100001d] hello@sample:password
-- [:01000010] hello@sample is login, secret is 7aabbffbdbee4ea1
-- [:0100001e] connect from 127.0.0.1:54520 (fd = 15)
-- [:0100001e] hello@sample:password
-- [:01000010] hello@sample is login, secret is ab3b953415f06be2
-- [:0100001f] connect from 127.0.0.1:37208 (fd = 16)
-- [:0100001f] hello@sample:password
-- [:01000010] hello@sample is login, secret is 3c1d17700bda086b
-- [:01000012] connect from 127.0.0.1:37218 (fd = 17)
-- [:01000012] hello@sample:password
-- [:01000010] hello@sample is login, secret is e797a8ca0644767a
-- [:01000019] connect from 127.0.0.1:50942 (fd = 18)
-- [:01000019] hello@sample:password
-- [:01000010] hello@sample is login, secret is 3ff2c3e34c21535c
-- [:0100001a] connect from 127.0.0.1:50946 (fd = 19)
-- [:0100001a] hello@sample:password
-- [:01000010] hello@sample is login, secret is d928a7ffa38f4fde
-- [:0100001b] connect from 127.0.0.1:50962 (fd = 20)
-- [:0100001b] hello@sample:password

-- 九个服务一个服务监听，其余服务轮流处理




-- msgserver
-- local login = require "snax.loginserver"
-- local crypt = require "skynet.crypt"
-- local skynet = require "skynet"
-- local server_list = {}

-- local server = {
--     host = "127.0.0.1",
--     port = 8001,
--     multilogin = false, -- disallow multilogin
--     name = "login_master",
-- }

-- function server.auth_handler(token)
--     -- the token is base64(user)@base64(server):base64(password)
--     local user, server, password = token:match("([^@]+)@([^:]+):(.+)")
--     user = crypt.base64decode(user)
--     server = crypt.base64decode(server)
--     password = crypt.base64decode(password)
--     skynet.error(string.format("%s@%s:%s", user, server, password))
--     assert(password == "password", "Invalid password")
--     return server, user
-- end

-- function server.login_handler(server, uid, secret)
--     local msgserver = assert(server_list[server], "unknow server")
--     skynet.error(string.format("%s@%s is login, secret is %s", uid, server, crypt.hexencode(secret)))
--     --将uid以及secret发送给登陆点，告诉登陆点，这个uid可以登陆，并且让登陆点返回一个subid
--     local subid = skynet.call(msgserver, "lua", "login", uid, secret) 
--     return subid --返回给客户端subid，用跟登录点握手使用
-- end

-- local CMD = {}

-- function CMD.register_gate(server, address)
--     skynet.error("cmd register_gate")
--     server_list[server] = address --记录已经启动的登录点
-- end

-- function server.command_handler(command, ...)
--     local f = assert(CMD[command])
--     return f(...)
-- end

-- login(server) --服务启动需要参数


-- $ ./skynet examples/conf
-- testmsgserver
-- [:01000010] LAUNCH snlua testmsgserver
-- [:01000012] LAUNCH snlua mylogin
-- [:01000019] LAUNCH snlua mylogin
-- [:0100001a] LAUNCH snlua mylogin
-- [:0100001b] LAUNCH snlua mylogin
-- [:0100001c] LAUNCH snlua mylogin
-- [:0100001d] LAUNCH snlua mylogin
-- [:0100001e] LAUNCH snlua mylogin
-- [:0100001f] LAUNCH snlua mylogin
-- [:01000020] LAUNCH snlua mylogin
-- [:01000012] login server listen at : 127.0.0.1 8001
-- [:01000022] LAUNCH snlua mymsgserver 16777234 #启动msgserver
-- [:01000022] Listen on 0.0.0.0:8002 #监听8002端口
-- register_handler        #向loginserver发送登录点注册信息
-- [:01000012] cmd register_gate #loginserver记录下来登录点的信息






local login = require "snax.loginserver"
local crypt = require "skynet.crypt"
local skynet = require "skynet"
local server_list = {} --登陆点
local login_users = {} --users

local server = {
    host = "127.0.0.1",
    port = 8001,
    multilogin = false, -- disallow multilogin
    name = "login_master",
}

function server.auth_handler(token)
    -- the token is base64(user)@base64(server):base64(password)
    local user, server, password = token:match("([^@]+)@([^:]+):(.+)")--通过正则表达式，解析出各个参数
    user = crypt.base64decode(user)
    server = crypt.base64decode(server)
    password = crypt.base64decode(password)
    skynet.error(string.format("%s@%s:%s", user, server, password))
    assert(password == "password", "Invalid password") -- 验证密码
    return server, user
end

function server.login_handler(server, uid, secret)
    local msgserver = assert(server_list[server], "unknow server")
    skynet.error(string.format("%s@%s is login, secret is %s", uid, server, crypt.hexencode(secret)))
    local last = login_users[uid]
    if  last then --判断是否登录，如果已经登录了，那就退出之前的登录
        skynet.call(last.address, "lua", "kick", uid, last.subid)
    end

    local id = skynet.call(msgserver, "lua", "login", uid, secret) --将uid以及secret发送给登陆点，让它做好准备，并且返回一个subid
    login_users[uid] = { address=msgserver, subid=id}
    return id
end

local CMD = {}

function CMD.register_gate(server, address)
    skynet.error("cmd register_gate")
    server_list[server] = address
end

function CMD.logout(uid, subid) --专门用来处理登出的数据清除，用户信息保存等
    local u = login_users[uid]
    if u then
        skynet.error(string.format("%s@%s is logout", skynet.address(u.address), uid))
        login_users[uid] = nil
    end
end

function server.command_handler(command, ...) --查找lua的回调，处理lua消息
    local f = assert(CMD[command])
    return f(...)
end

login(server) --服务启动需要参数


